package com.victor.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.victor.entity.User;
import com.victor.service.RegisteruserService;
import com.victor.utils.Msg;
import com.victor.utils.sms.SmsSend;

/**
 * 沉睡用户 批量发送短信
 * 
 * @author zhangbin
 *
 */
@RestController
public class ThreadController {

	// 通过注解引入配置
	@Resource(name = "defaultThreadPool")
	private ThreadPoolTaskExecutor executor;

	// 注册用户管理service
	@Autowired
	private RegisteruserService service;

	@RequestMapping("/sleepUserSendSms")
	public Msg sleepUserSendSms(int[] userids) throws Exception {

		List<Integer> list = new ArrayList<Integer>();
		// 使用Future方式执行多任务
		// 生成一个集合
		List<Future<Integer>> futures = new ArrayList<>();

		// 通过传入的userids查询需要发送短信的用户列表
		List<User> users = service.getUserByUserids(userids);

		for (User user : users) {
			// 并发处理
			if (user.getPhone() != null) {
				Future<Integer> future = executor.submit(new Callable<Integer>() {
					// 发送短信
					public Integer call() throws Exception {
						return SmsSend.smsSendMessage(user.getPhone(), "11306", "");
					}
				});
				futures.add(future);
			}
		}

		// 查询任务执行的结果
		for (Future<Integer> future : futures) {
			while (true) {// CPU高速轮询：每个future都并发轮循，判断完成状态然后获取结果，这一行，是本实现方案的精髓所在。即有10个future在高速轮询，完成一个future的获取结果，就关闭一个轮询
				if (future.isDone() && !future.isCancelled()) {// 获取future成功完成状态，如果想要限制每个任务的超时时间，取消本行的状态判断+future.get(1000*1,TimeUnit.MILLISECONDS)+catch超时异常使用即可。
					Integer i = future.get();// 获取结果
					list.add(i);
					break;// 当前future获取结果完毕，跳出while
				} else {
					Thread.sleep(1);// 每次轮询休息1毫秒（CPU纳秒级），避免CPU高速轮循耗空CPU---》新手别忘记这个
				}
			}
		}
		//将结果放回user实体中
		for (int i = 0; i < userids.length; i++) {
			users.get(i).setSms_if_success(list.get(i));
		}
		
		return Msg.success().add("users", users);
	}
}
